package de.fstyle.android.worldcanvas.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.json.JSONArray;
import org.json.JSONException;

import de.fstyle.android.worldcanvas.Installation;
import de.fstyle.android.worldcanvas.model.ObjectDescription;

import android.content.Context;
import android.location.Location;
import android.provider.Settings;
import android.util.Log;

public class HttpUtils {
	
	public static final String DATA_CONTENT_DETAILS_TYPE = "data.contentDetails.type";
	public static final String META_VISIBILITY_GLOBAL = "meta.visibilityGlobal";
	public static final String META_INSTALL_ID = "meta.installId";
	public static final String META_DEVICE_ID = "meta.deviceId";
	
	private static final String GEO_LONGITUDE = "geo.longitude";
	private static final String GEO_LATITUDE = "geo.latitude";
	private static final String GEO_ACCURACY = "geo.accuracy";
	private static final String GEO_PROVIDER = "geo.provider";
	private static final String GEO_TIMESTAMP = "geo.timestamp";

	public static final String POST_URL = 
//			"http://132.187.15.110:8080/ubicon-webapp/api/v1/packets";
			"http://cs.everyaware.eu/api/v1/packets";
	
	public static final String GET_URL = 
//			"http://132.187.15.110:8080/ubicon-webapp/api/v1/data/packets?data.contentDetails.type=color&limit=1";
			"http://cs.everyaware.eu/api/v1/data/packets?data.contentDetails.type=color";
	
	public static final String DATE_FORMAT_STRING = 
			"yyyy-MM-dd_HH:mm:ss.SSSz";
	
	public static final DateFormat DATE_FORMAT = 
			new SimpleDateFormat(DATE_FORMAT_STRING, Locale.US);
	
	public static final String LOG_TAG = "http";
	
	public static void addGeoHeaders(
			Location location,
			AbstractHttpMessage message) {
		
		message.addHeader(GEO_LONGITUDE, 
				Double.toString(location.getLongitude()));
		message.addHeader(GEO_LATITUDE, 
				Double.toString(location.getLatitude()));
		
		message.addHeader(GEO_ACCURACY, 
				Double.toString(location.getAccuracy()));
		message.addHeader(GEO_PROVIDER, 
				location.getProvider());
		
		message.addHeader(GEO_TIMESTAMP, 
				DATE_FORMAT.format(new Date(location.getTime())));
	}

	public static JSONArray get(Location location) 
			throws ClientProtocolException, JSONException, IOException {
		
		return get(location, 1);
	}
	
	public static JSONArray get(Location location, int limit) 
			throws JSONException, ClientProtocolException, IOException {

		String url = GET_URL;
		
		if (location != null) {
			double lon = location.getLongitude();
			double lat = location.getLatitude();
			double lonMin = lon - 0.0002;
			double lonMax = lon + 0.0002;
			double latMin = lat - 0.0001;
			double latMax = lat + 0.0001;
			url = url + String.format(
					Locale.US,
					"&limit=%d" +
					"&geo.boundingBox=%f,%f,%f,%f", 
					limit, 
					lonMin, latMin, lonMax, latMax);
		}
		
		Log.d(LOG_TAG, url);
		
		HttpClient httpClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);

		// these are not url parameters
//		httpGet.getParams().setParameter("contentType", "color");
//		httpGet.getParams().setParameter("limit", "1");
		
		
		HttpResponse response = httpClient.execute(httpGet);
		
		String content = convertToString(response.getEntity().getContent());
		JSONArray jsonArray = new JSONArray(content);
		return jsonArray;
	}
	
	public static void send(
			ObjectDescription<?> objectDescription,
			Context context) {
		
		// create a new HttpClient and Post header
		HttpClient httpClient = new DefaultHttpClient();
		HttpPost httpPost = new HttpPost(POST_URL);

		// set meta headers
		httpPost.addHeader(META_DEVICE_ID, Settings.Secure.ANDROID_ID);
		httpPost.addHeader(META_INSTALL_ID, Installation.id(context));
		httpPost.addHeader(META_VISIBILITY_GLOBAL, "DETAILS");
		httpPost.addHeader(DATA_CONTENT_DETAILS_TYPE, "color");
		
		// set geo headers
		Location location = objectDescription.getLocation();
		if (location != null) {
			Log.d(LOG_TAG, "setting location");
			addGeoHeaders(location, httpPost);
		} else {
			Log.d(LOG_TAG, "no location available");
		}
		
		try {

			// generate entity
			String objectString = objectDescription.getObject().toString();
			StringEntity stringEntity = new StringEntity(objectString);

			// set entity
			httpPost.setEntity(stringEntity);
			
			// set paramteres
			HttpParams httpParams = new BasicHttpParams();
			httpParams.setParameter("test", "test");
			httpPost.setParams(httpParams);
			
			// execute HTTP Post request
			HttpResponse response = httpClient.execute(httpPost);
			Log.d(
					LOG_TAG, 
					"Status code: " 
							+ response.getStatusLine().getStatusCode());

		} catch (ClientProtocolException e) {
			Log.d(LOG_TAG, "error", e);
		} catch (IOException e) {
			Log.d(LOG_TAG, "error", e);
		}

	}
	
	public static String convertToString(InputStream inputStream) 
			throws IOException {
		
		InputStreamReader inputStreamReader = 
				new InputStreamReader(inputStream);
		
		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

		StringBuilder stringBuilder = new StringBuilder();
		String line = bufferedReader.readLine();
		while (line != null) {
			stringBuilder.append(line + System.getProperty("line.separator"));
			line = bufferedReader.readLine();
		}
		
		return stringBuilder.toString();
	}
}
